﻿using Kingdee.BOS;
using Kingdee.BOS.Core.DynamicForm;
using Kingdee.BOS.Core.List;
using Kingdee.BOS.Core.List.PlugIn;
using Kingdee.BOS.Core.List.PlugIn.Args;
using Kingdee.BOS.Core.Metadata.ConvertElement;
using Kingdee.BOS.Model.Bill;
using Kingdee.BOS.Util;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RK.ListBillPlugin.Ronma
{
    [Description("Ronma:第三方下推"), HotUpdate]
    public class ListToFeedMtrl : AbstractListPlugIn
    {
        private const string vFormId = "PRD_MO";
        /// <summary>
        /// JDA单据的FormId
        /// </summary>
        private const string JDAFormId = "PRD_PPBOM";
        /// <summary>
        /// JDB单据的FormId
        /// </summary>
        private const string JDBFormId = "YCVN_SCBLD";
        /// <summary>
        /// 点击下推、上下查菜单之后，显示下推界面、联查界面之前触发
        /// </summary>
        /// <param name="e"></param>
        /// <remarks>
        /// 可以利用此事件，为下推界面添加目标单据
        /// </remarks>
        public override void OnShowConvertOpForm(ShowConvertOpFormEventArgs e)
        {
            base.OnShowConvertOpForm(e);
            var formId = e.SelectedRows.Select(s => s.FormID).FirstOrDefault();
            if (formId != null && formId == vFormId)
            {
                if (e.ConvertOperation == FormOperationEnum.Push)//下推
                {
                    DoPush(e);
                }
                //if (e.ConvertOperation == FormOperationEnum.TrackDown)
                //{// 下查
                // // 采购订单 (表面上的源单) -> JDA (真实源单) -> JDB (真实目标单)
                //    //DoTrackDown(e);
                //}
            }
            //if (formId != null && formId == JDBFormId)
            //{
            //    DoTrackUp(e);
            //}
        }
        /// <summary>
        /// 在下推界面，确定好目标单，点击确定，开始下推后触发
        /// </summary>
        /// <param name="e"></param>
        /// <remarks>
        /// 可以利用此事件，调整源单内码;
        ///
        /// 本演示代码，本事件仅用于下推，
        /// 把采购订单的内码，替换为真实源单JDA单据内码
        /// </remarks>
        public override void OnGetConvertRule(GetConvertRuleEventArgs e)
        {
            base.OnGetConvertRule(e);
            if (e.ConvertOperation == FormOperationEnum.Push && e.TargetFormId.EqualsIgnoreCase(JDBFormId))
            {
                var selectIds = e.SelectedRows.Select(s => s.EntryPrimaryKeyValue).ToList();
                string filterString = $"FMOEntryID in ({string.Join(",", selectIds)})";
                var ppbomfid = Api.ExecuteBillQuery(this.Context, JDAFormId, "fid", filterString, "fid", 2000);
                if (ppbomfid == null || ppbomfid.Count == 0)
                {
                    return;
                }
                List<string> sFidList = new List<string>();
                List<string> sEidList = new List<string>();
                foreach (var pbom in ppbomfid)
                {
                    sFidList.Add(pbom[0].ToString());
                    //sEidList.Add(pbom[1].ToString());
                }
                // 用户选择下推到JDB，采用的是第三方下推，需要把源单内码调整为JDA的内码
                // 根据实际业务关系，由当前选择的采购订单找到关联的JDA单据
                // 演示代码并没有这种关系，略过，直接填写具体的JDA单据内码
                List<ListSelectedRow> JDARows = new List<ListSelectedRow>();
                JDARows.Add(new ListSelectedRow(string.Join(",", sFidList.Distinct()), "", 0, JDAFormId));
                // 把源单内码替换为JDA的内码
                e.SelectedRows = JDARows.ToArray();
            }
        }
        /// <summary>
        /// 联查界面，用户点击关联单据之后，触发本事件
        /// </summary>
        /// <param name="e"></param>
        /// <remarks>
        /// 可以利用此事件，调整关联单据内码，以控制关联单据列表的显示内容
        ///
        /// 本演示代码，本事件仅用于上查，
        /// 把真实源单采购申请单，替换为表面上的生产订单内码
        /// </remarks>
        public override void OnShowTrackResult(ShowTrackResultEventArgs e)
        {
            base.OnShowTrackResult(e);
            if (e.TrackOperation == FormOperationEnum.TrackDown)
            {// 下查
                if (e.TargetFormKey.EqualsIgnoreCase(JDBFormId))
                {// 需要上查生产订单
                    // e.TrackResult 中存储了真实源单的信息，需要替换为表面上源单
                    //var tres = e.TrackResult;
                    // TODO: 根据e.TrackResult中的真实源单，寻找对应的表面上的源单
                    // 本演示代码，忽略上述寻找过程，直接替换为生产订单单据体内码100003
                    //BillModel trackResult = BillNode.Create("PRD_MO", "", null);
                    //trackResult.AddLinkCopyData(new List<string>() { "100003" });

                    // 替换源单内码：由真实源单(采购申请单)，替换为表面上的源单(生产订单)
                    //e.TrackResult = trackResult;
                    // 替换之后，系统将显示上面指定的生产订单单据体行
                }
            }
        }

        private void DoTrackUp(ShowConvertOpFormEventArgs e)
        {
            if (e.ConvertOperation == FormOperationEnum.TrackUp)
            {// 上查
                // 在上游单据列表中，增加生产订单：供用户双击查询生产订单
                ConvertBillElement PRD_MOInfo = new ConvertBillElement();
                PRD_MOInfo.FormID = vFormId;
                PRD_MOInfo.Name = new LocaleValue("生产订单");
                e.BillList.Add(PRD_MOInfo);
                // 因为本单与生产订单并没有直接关系，需要借助真实源单（采购申请单）搭一个桥
                // 上查操作ReplaceRelation参数说明：
                // e.AddReplaceRelation(真实源单FormId(采购申请), 表面上的源单FormId(生产订单));
                // 用户双击生产订单时，系统会先找到真实的源单(采购申请)单，
                // 然后插件在OnShowTrackResult事件中，替换源单
                e.AddReplaceRelation(JDAFormId, "PRD_MO");
            }
        }

        private void DoTrackDown(ShowConvertOpFormEventArgs e)
        {
            // 把真实目标单(JDB)，添加到可选下游单据列表
            ConvertBillElement JDBInfo = new ConvertBillElement();
            JDBInfo.FormID = JDBFormId;
            //JDBInfo.Name = new LocaleValue("生产超耗申请单");
            e.BillList.Add(JDBInfo);
            // 标记目标单(JDB)为第三方下推，其真实源单为JDA
            // 下推、选单操作，ReplaceRelation构造参数说明：ReplaceRelation(真实源单FormId, 真实目标单FormId);
            // 上查操作，ReplaceRelation构造参数说明：ReplaceRelation(真实源单FormId, 表面上的源单FormId);
            // 下查操作，ReplaceRelation构造参数说明：ReplaceRelation(真实源单FormId, 正式目标单FormId);
            ReplaceRelation JDAToJDB = new ReplaceRelation(JDAFormId, JDBFormId);
            // 当前采购订单分录内码
            JDAToJDB.TargetLinkId = new List<string>();
            var tId = e.SelectedRows.Select(s => s.EntryPrimaryKeyValue).ToList();
            JDAToJDB.TargetLinkId.Add(string.Join(",", tId)); // 100047仅用于演示，实际运行时，需要取e.SelectedRows中的单据体内码
            // 对应的JDA单据体内码，联查时，将以此内码作为源单内码，搜索JDA下推的JDB单据
            //JDAToJDB.SourceLinkId = new List<string>();
            //JDAToJDB.SourceLinkId.Add("100135"); // 100017仅用于演示，实际运行时，需根据关系自行查找第三方源单的内码
            e.ReplaceRelations.Add(JDAToJDB);
        }

        private void DoDraw(ShowConvertOpFormEventArgs e)
        {
            //不实现
        }

        private void DoPush(ShowConvertOpFormEventArgs e)
        {
            // 把真实目标单(JDB)，添加到可选下游单据列表
            ConvertBillElement JDBInfo = new ConvertBillElement();
            JDBInfo.FormID = JDBFormId;
            JDBInfo.Name = new LocaleValue("生产超耗申请单");
            e.BillList.Add(JDBInfo);
            // 标记目标单(JDB)为第三方下推，其真实源单为JDA
            // 下推操作，ReplaceRelation构造参数说明：
            // ReplaceRelation(真实源单FormId, 真实目标单FormId);
            ReplaceRelation JDAToJDB = new ReplaceRelation(JDAFormId, JDBFormId);
            e.ReplaceRelations.Add(JDAToJDB);
        }
    }
}
